package com.nus.fellowmark.modules.assignment.controller;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Map;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;

import com.nus.fellowmark.common.response.ServerResponseEntity;
import com.nus.fellowmark.entity.ReviewEntity;
import com.nus.fellowmark.modules.assignment.dto.ReviewDTO;
import com.nus.fellowmark.modules.assignment.service.ReviewService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.nus.fellowmark.common.utils.PageUtils;

/**
 * 
 *
 * @author Goh Yen Ther
 * @email goh.yenther@gmail.com
 * @date 2023-03-04  
 */
@RestController
@RequestMapping("review")
@CrossOrigin
public class ReviewController {
    @Autowired
    private ReviewService reviewService;


    @SaCheckRole(value = {"admin", "super-admin", "staff"}, mode = SaMode.OR)
    @ApiOperation("list reviews")
    @RequestMapping("/list")
    public ServerResponseEntity list(@RequestParam Map<String, Object> params){
        PageUtils page = reviewService.queryPage(params);

        return ServerResponseEntity.success("page", page);
    }


    @ApiOperation("select review by id ")
    @RequestMapping("/info/{id}")
    public ServerResponseEntity info(@PathVariable("id") Integer id){
		ReviewEntity review = reviewService.getById(id);

        return ServerResponseEntity.success("review", review);
    }

    @ApiOperation("select review by pairingId and submissionId")
    @RequestMapping("/pair/{pairingId}/submission/{submissionId}")
    public ServerResponseEntity selectByPairAndSubmission(@PathVariable("pairingId") Integer pairingId, @PathVariable("submissionId") Integer submissionId){
		ReviewEntity review = reviewService.getReviewByPairAndSubmission(pairingId, submissionId);

        if (review == null) { // no existing review in database
            return ServerResponseEntity.success("review", null);
        }
        else{
            // Convert existing review Blob data back to string
            Charset charset = Charset.forName("UTF-8");
            String pdfAnnot = new String(review.getReviewPdfAnnot(), charset);

            return ServerResponseEntity.success("review", pdfAnnot);
        }  
    }

    @ApiOperation("save review")
    @RequestMapping("/save")
    public ServerResponseEntity save(@RequestBody ReviewDTO reviewDTO){
        // check if there is existing review
        ReviewEntity reviewExist = reviewService.getReviewByPairAndSubmission(reviewDTO.getPairingId(), reviewDTO.getSubmissionId());
        
        if (reviewExist == null) { // no existing review, create new review to save in database
            ReviewEntity review = new ReviewEntity();
            review.setPairingId(reviewDTO.getPairingId());
            review.setSubmissionId(reviewDTO.getSubmissionId());
            try {
                review.setReviewPdfAnnot(reviewDTO.getReviewPdfAnnot().getBytes("UTF-8"));
            } catch (UnsupportedEncodingException err) {
                err.printStackTrace();
            }
            reviewService.save(review);
            return ServerResponseEntity.success();
        }
        else { // existing review, update the blob directly in database
            try {
                reviewExist.setReviewPdfAnnot(reviewDTO.getReviewPdfAnnot().getBytes("UTF-8"));
            } catch (UnsupportedEncodingException err) {
                err.printStackTrace();
            }
            return update(reviewExist);
        }
    }

    @ApiOperation("update review")
    @RequestMapping("/update")
    public ServerResponseEntity update(@RequestBody ReviewEntity review){
		reviewService.updateById(review);

        return ServerResponseEntity.success();
    }

    @ApiOperation("delete review")
    @RequestMapping("/delete")
    public ServerResponseEntity delete(@RequestBody Integer[] ids){
		reviewService.removeByIds(Arrays.asList(ids));

        return ServerResponseEntity.success();
    }

}
